# -*- coding: utf-8 -*-

import unittest
import os.path

from kivy.lang import Builder

from welcome_screen import WelcomeScreen
from game_config import GameConfig
from start_game import StartGame
from add_player import AddPlayerScreen
from add_words import AddWords
from players_order import PlayersOrderWidget
from from_to import FromToWidget
from before_round_screen import BeforeRoundScreen
from guess_word import GuessWordScreen
from results_of_one_pair import ResultsOfOnePair
from ui.game_results import GameResults
from presenter_mock import PresenterMock
from model import gamestate
from model.gamestate import Phase, Settings


class IntegrationTest(unittest.TestCase):
    def setUp(self):
        self.presenter = PresenterMock(Phase.GAME_CONFIG)
        self.gamestate = gamestate.GameState(None, None,
                                             None, None, None, None,
                                             Settings())

    def prepair_game(self):
        self.widget = WelcomeScreen(self.gamestate, self.presenter)
        #self.gamestate.remote_id = 777
        self.widget.start_game()
        self.assertEquals(self.presenter.is_phase_changed, True)

        self.presenter = PresenterMock(Phase.START_GAME)
        self.widget = GameConfig(self.gamestate, self.presenter)
        self.assertEquals(self.presenter.is_phase_changed, False)
        self.widget.change_time(5)
        self.widget.read_words_count("35")
        self.assertEquals(self.widget.words_count, 35)
        self.widget.change_words_count(-1)
        self.widget.change_words_count(-1)
        self.assertEquals(self.presenter.is_phase_changed, False)
        self.widget.next_view()
        self.assertEquals(self.gamestate.settings.time_per_round_sec, 25)
        self.assertEquals(self.widget.words_count, 33)
        self.assertEquals(self.gamestate.settings.words_number, 33)
        self.assertEquals(self.presenter.is_phase_changed, True)
        #self.assertEquals(self.gamestate.remote_id, 777)

    def prepair_players(self):
        current_players = gamestate.Players([])
        current_words = 0

        for player in range(6):
            self.presenter = PresenterMock(Phase.ADD_PLAYER)
            self.widget = StartGame(self.gamestate, self.presenter)
            self.assertEquals(self.presenter.is_phase_changed, False)
            self.assertEquals(self.gamestate.players, current_players)
            self.widget.add_player()
            self.assertEquals(self.presenter.is_phase_changed, True)

            self.presenter = PresenterMock(Phase.ADD_WORDS)
            self.widget = AddPlayerScreen(self.gamestate, self.presenter)
            self.assertEquals(self.presenter.is_phase_changed, False)
            self.widget.player_name = 'player' + str(player)
            self.widget.on_add_user_pressed()
            self.assertEquals(self.gamestate.current_added_player.name,
                              'player' + str(player))
            self.assertEquals(self.presenter.is_phase_changed, True)

            self.presenter = PresenterMock(Phase.START_GAME)
            self.widget = AddWords(self.gamestate, self.presenter)
            self.widget.word_input.text = u'кролик' + str(player)
            self.widget.word_list.on_add_word(self.widget.word_input)
            self.assertEqual(self.widget.word_input.text, '')
            self.assertEqual(len(self.gamestate.current_added_player.words), 1)
            self.assertEqual(self.gamestate.current_added_player.words[0].text,
                             u'кролик' + str(player))
            self.assertEqual(self.gamestate.current_added_player.
                             words[0].owner,
                             self.gamestate.current_added_player)
            self.assertEqual(self.presenter.is_phase_changed, False)

            self.widget.word_input.text = u'шапка' + str(player)
            self.widget.word_list.on_add_word(self.widget.word_input)
            self.assertEqual(len(self.gamestate.current_added_player.words), 2)
            self.widget.word_list.del_word(self.widget.word_list.children[1])
            self.assertEqual(len(self.gamestate.current_added_player.words), 1)
            self.assertEqual(self.presenter.is_phase_changed, False)

            self.widget.from_dict()
            self.assertEqual(self.widget.cur_count, 33)
            self.assertEqual(len(self.gamestate.current_added_player.words),
                             33)
            self.assertEqual(self.presenter.is_phase_changed, False)

            current_players.players.append(self.gamestate.current_added_player)

            self.widget.finish()
            self.assertEqual(self.presenter.is_phase_changed, True)

            self.presenter = PresenterMock(Phase.PLAYERS_ORDER)
            self.widget = StartGame(self.gamestate, self.presenter)
            current_words += 33
            self.assertEqual(self.gamestate.current_added_player, None)
            self.assertEqual(len(self.gamestate.hat.words),
                             current_words)
            self.widget.start_game()
            self.assertEquals(self.presenter.is_phase_changed, True)

        self.presenter = PresenterMock(Phase.FROM_TO)
        self.widget = PlayersOrderWidget(self.gamestate, self.presenter)
        self.assertFalse(self.presenter.is_phase_changed)
        self.widget.finish()
        self.assertEquals(self.presenter.is_phase_changed, True)

    def prepair_round(self, player_1, player_2):
        self.presenter = PresenterMock(Phase.BEFORE_ROUND)
        self.widget = FromToWidget(self.gamestate, self.presenter)
        self.assertEquals(self.presenter.is_phase_changed, False)
        self.assertEquals(self.gamestate.game_round.players_pair,
                          (self.gamestate.players.players[player_1],
                           self.gamestate.players.players[player_2]))
        self.assertEquals(self.gamestate.game_round.time_left_sec, 25)

        self.assertEquals(self.presenter.is_phase_changed, False)
        self.widget.finish()
        self.assertEquals(self.presenter.is_phase_changed, True)

        self.presenter = PresenterMock(Phase.GUESS_WORD)
        self.widget = BeforeRoundScreen(self.gamestate, self.presenter)
        self.assertEquals(self.presenter.is_phase_changed, False)
        self.widget.update(3.1)
        self.assertEquals(self.presenter.is_phase_changed, True)

    def test_all_guessing(self):
        self.prepair_game()
        self.prepair_players()

        player_1 = 0
        player_2 = 3

        for i in range(33):

            self.prepair_round(player_1, player_2)
            self.presenter = PresenterMock(Phase.RESULTS_OF_ONE_PAIR)
            self.widget = GuessWordScreen(self.gamestate, self.presenter)
            for i in range(4):
                words_len = len(self.gamestate.hat.words)
                old_word = self.gamestate.game_round.current_word
                self.widget.guessed()
                new_word = self.gamestate.game_round.words[-1]
                self.assertEquals(old_word, new_word.word)
                self.assertEquals(gamestate.WordGuessResult.GUESS,
                                  new_word.result)
                new_len = len(self.gamestate.hat.words)
                self.assertEquals(self.presenter.is_phase_changed, False)
                self.assertEquals(words_len - 1, new_len)

            self.widget.update_state(50)
            self.assertEquals(self.presenter.is_phase_changed, False)
            self.widget.guessed()
            new_word = self.gamestate.game_round.current_word
            self.assertEquals(self.presenter.is_phase_changed, True)
            self.assertEquals(len(self.gamestate.game_round.words), 5)
            self.assertEquals(new_word, None)

            self.presenter = PresenterMock(Phase.FROM_TO)
            self.widget = ResultsOfOnePair(self.gamestate, self.presenter)
            self.widget.to_next()
            self.assertEquals(self.presenter.is_phase_changed, True)
            self.assertEquals(self.gamestate.game_round, None)
            self.assertEquals(len(self.gamestate.rounds[-1].words), 5)

            player_1 = (player_1 + 1) % 6
            player_2 = (player_2 + 1) % 6

        self.prepair_round(player_1, player_2)

        self.presenter = PresenterMock(Phase.RESULTS_OF_ONE_PAIR)
        self.widget = GuessWordScreen(self.gamestate, self.presenter)

        for i in range(33):
            self.assertEquals(self.presenter.is_phase_changed, False)
            self.widget.guessed()

        self.assertEquals(self.presenter.is_phase_changed, True)
        self.assertEquals(len(self.gamestate.hat.words), 0)
        self.assertEquals(self.gamestate.game_round.current_word, None)
        #self.assertEquals(self.gamestate.remote_id, 777)

        self.presenter = PresenterMock(Phase.GAME_RESULTS)
        self.widget = ResultsOfOnePair(self.gamestate, self.presenter)
        #self.assertEquals(self.gamestate.remote_id, 777)
        self.widget.to_next()
        self.presenter = PresenterMock(Phase.WELCOME)
        self.widget = GameResults(self.gamestate, self.presenter)
        self.widget.new_game()
        self.gamestate.clear()
        self.assertEquals(self.gamestate.remote_id, None)

    def prepair_one_word(self):
        self.prepair_game()
        self.prepair_players()

        player_1 = 0
        player_2 = 3

        self.prepair_round(player_1, player_2)

        self.presenter = PresenterMock(Phase.RESULTS_OF_ONE_PAIR)
        self.widget = GuessWordScreen(self.gamestate, self.presenter)

        for i in range(33 * 6 - 1):
            self.assertEquals(self.presenter.is_phase_changed, False)
            words_len = len(self.gamestate.hat.words)
            old_word = self.gamestate.game_round.current_word
            self.widget.guessed()
            new_word = self.gamestate.game_round.words[-1]
            self.assertEquals(old_word, new_word.word)
            self.assertEquals(gamestate.WordGuessResult.GUESS,
                              new_word.result)
            new_len = len(self.gamestate.hat.words)
            self.assertEquals(words_len - 1, new_len)


if __name__ == '__main__':
    unittest.main()
